function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import Chain from "./chain";
import { AndOperator, CatchOperator, ForOperator, IfOperator, IteratorOperator, NodeOperator, NotOperator, OrOperator, SwitchOperator, ThenOperator, WhenOperator, WhileOperator, ChainOperator } from "./el";
import { ConditionTypeEnum, NodeTypeEnum } from "../constant";
/**
 * 将EL表达式的JSON表示，构造成ELNode模型表示。
 * EL表达式的模型表示：数据结构本质上是一个树形结构。
 * 例如一个串行编排(THEN)：
 * (1) EL表达式形式：THEN(a, b, c, d)
 * (2) JSON表示形式：
 * {
    type: ConditionTypeEnum.THEN,
    children: [
      { type: NodeTypeEnum.COMMON, id: 'a' },
      { type: NodeTypeEnum.COMMON, id: 'b' },
      { type: NodeTypeEnum.COMMON, id: 'c' },
      { type: NodeTypeEnum.COMMON, id: 'd' },
    ],
  }
 * (3) 通过ELNode节点模型进行表示的组合关系为：
                                          ┌─────────────────┐
                                      ┌──▶│  NodeOperator   │
                                      │   └─────────────────┘
                                      │   ┌─────────────────┐
                                      ├──▶│  NodeOperator   │
  ┌─────────┐    ┌─────────────────┐  │   └─────────────────┘
  │  Chain  │───▶│  ThenOperator   │──┤   ┌─────────────────┐
  └─────────┘    └─────────────────┘  ├──▶│  NodeOperator   │
                                      │   └─────────────────┘
                                      │   ┌─────────────────┐
                                      └──▶│  NodeOperator   │
                                          └─────────────────┘
 */
var ELBuilder = /*#__PURE__*/function () {
  function ELBuilder() {
    _classCallCheck(this, ELBuilder);
  }
  _createClass(ELBuilder, null, [{
    key: "build",
    value: function build(data) {
      return builder(data);
    }
  }, {
    key: "createELNode",
    value: function createELNode(type, parent, id) {
      switch (type) {
        // 1. 编排类型
        case ConditionTypeEnum.THEN:
        case ConditionTypeEnum.SER:
          return ThenOperator.create(parent);
        case ConditionTypeEnum.WHEN:
        case ConditionTypeEnum.PAR:
          return WhenOperator.create(parent);
        case ConditionTypeEnum.SWITCH:
          return SwitchOperator.create(parent);
        case ConditionTypeEnum.IF:
          return IfOperator.create(parent);
        case ConditionTypeEnum.FOR:
          return ForOperator.create(parent);
        case ConditionTypeEnum.WHILE:
          return WhileOperator.create(parent);
        case ConditionTypeEnum.ITERATOR:
          return IteratorOperator.create(parent);
        case ConditionTypeEnum.CATCH:
          return CatchOperator.create(parent);
        case ConditionTypeEnum.AND:
          return AndOperator.create(parent);
        case ConditionTypeEnum.OR:
          return OrOperator.create(parent);
        case ConditionTypeEnum.NOT:
          return NotOperator.create(parent);
        case ConditionTypeEnum.CHAIN:
          return ChainOperator.create(parent);
        case ConditionTypeEnum.PRE:
        case ConditionTypeEnum.FINALLY:
        case ConditionTypeEnum.BREAK:
        case ConditionTypeEnum.ABSTRACT:
        case ConditionTypeEnum.DEFAULT:
          return ThenOperator.create(parent);
        // 2. 节点类型
        case NodeTypeEnum.COMMON:
        default:
          // return NodeOperator.create(parent, type as NodeTypeEnum);
          return NodeOperator.create(parent, type, id);
      }
    }
  }]);
  return ELBuilder;
}();
export { ELBuilder as default };
export function builder(data) {
  var chain = new Chain();
  if (Array.isArray(data)) {
    data.forEach(function (item) {
      var next = parse({
        parent: chain,
        data: item
      });
      if (next) {
        chain.appendChild(next);
      }
    });
  } else {
    var next = parse({
      parent: chain,
      data: data
    });
    if (next) {
      chain.appendChild(next);
    }
  }
  return chain;
}
export function parse(_ref) {
  var parent = _ref.parent,
    data = _ref.data;
  if (!(data !== null && data !== void 0 && data.type)) {
    return undefined;
  }
  switch (data.type) {
    // 1、编排类：顺序、分支、循环
    case ConditionTypeEnum.THEN:
    case ConditionTypeEnum.SER:
      return parseOperator({
        parent: new ThenOperator(parent),
        data: data
      });
    case ConditionTypeEnum.WHEN:
    case ConditionTypeEnum.PAR:
      return parseOperator({
        parent: new WhenOperator(parent),
        data: data
      });
    case ConditionTypeEnum.SWITCH:
      return parseOperator({
        parent: new SwitchOperator(parent),
        data: data
      });
    case ConditionTypeEnum.IF:
      return parseOperator({
        parent: new IfOperator(parent),
        data: data
      });
    case ConditionTypeEnum.FOR:
      return parseOperator({
        parent: new ForOperator(parent),
        data: data
      });
    case ConditionTypeEnum.WHILE:
      return parseOperator({
        parent: new WhileOperator(parent),
        data: data
      });
    case ConditionTypeEnum.ITERATOR:
      return parseOperator({
        parent: new IteratorOperator(parent),
        data: data
      });
    case ConditionTypeEnum.CATCH:
      return parseOperator({
        parent: new CatchOperator(parent),
        data: data
      });
    case ConditionTypeEnum.AND:
      return parseOperator({
        parent: new AndOperator(parent),
        data: data
      });
    case ConditionTypeEnum.OR:
      return parseOperator({
        parent: new OrOperator(parent),
        data: data
      });
    case ConditionTypeEnum.NOT:
      return parseOperator({
        parent: new NotOperator(parent),
        data: data
      });
    case ConditionTypeEnum.CHAIN:
      return parseOperator({
        parent: new ChainOperator(parent, data.id),
        data: data
      });
    case ConditionTypeEnum.PRE:
    case ConditionTypeEnum.FINALLY:
    case ConditionTypeEnum.BREAK:
    case ConditionTypeEnum.ABSTRACT:
    case ConditionTypeEnum.DEFAULT:
      return parseOperator({
        parent: new ThenOperator(parent),
        data: data,
        type: data.type
      });
    // 2、组件类：顺序、分支、循环
    case NodeTypeEnum.COMMON:
    default:
      return new NodeOperator(parent, data.type, data.id, data.properties);
  }
}
function parseOperator(_ref2) {
  var parent = _ref2.parent,
    data = _ref2.data,
    type = _ref2.type;
  var condition = data.condition,
    _data$children = data.children,
    children = _data$children === void 0 ? [] : _data$children,
    properties = data.properties;
  if (condition) {
    var conditionNode = parse({
      parent: parent,
      data: condition
    });
    if (conditionNode) {
      parent.condition = conditionNode;
    }
  }
  if (children && children.length) {
    children.forEach(function (child) {
      var childNode = parse({
        parent: parent,
        data: child
      });
      if (childNode) {
        parent.appendChild(childNode);
      }
    });
  }
  if (properties) {
    parent.setProperties(properties);
  }
  if (type) {
    parent.type = type;
  }
  return parent;
}